package com.kedacom.demo.spring.websocket;

import java.io.IOException;
import java.util.concurrent.ExecutionException;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;

public abstract class WebSocketClient extends AbstractWebSocketClientHandler {

	private String url;
	private StandardWebSocketClient webSocketClient;
	private WebSocketSession webSocketSession;
	private boolean connected = false;
	private boolean autoReconnect = true; // 断链后是否自动重连
	private int reconnectInterval = 3000; // 断链重连间隔（毫秒）

	public WebSocketClient() {
	}

	public WebSocketClient(String url) {
		this.url = url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public void setAutoReconnect(boolean autoReconnect) {
		this.autoReconnect = autoReconnect;
	}

	public void setReconnectInterval(int reconnectInterval) {
		this.reconnectInterval = reconnectInterval;
	}

	@PostConstruct
	public void init() {
		try {
			webSocketClient = new StandardWebSocketClient();
			webSocketSession = webSocketClient.doHandshake(this, url).get();
		} catch (InterruptedException | ExecutionException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		super.afterConnectionEstablished(session);
		connected = true;
	}

	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
		super.afterConnectionClosed(session, status);
		connected = false;
		// if (webSocketSession != null) {
		// try {
		// webSocketSession.close(status);
		// } catch (Exception e) {
		// e.printStackTrace();
		// } finally {
		// webSocketSession = null;
		// }
		// }
		if (this.autoReconnect) {
			reconnect();
		}
	}

	protected void reconnect() {
		while (!connected)
			try {
				this.init();
				Thread.sleep(this.reconnectInterval);
			} catch (Exception e) {
				logger.error("reconnect error {}", e.getMessage());
			}
	}

	/**
	 * 发送消息
	 */
	public void sendMessage(String message) {
		if (webSocketSession == null) {
			throw new RuntimeException("WebSocket未建链成功。");
		}
		try {
			webSocketSession.sendMessage(new TextMessage(message));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@PreDestroy
	public void destory() {
		this.autoReconnect = false;
		if (webSocketSession == null) {
			return;
		}
		try {
			webSocketSession.close(CloseStatus.NORMAL.withReason("客户端主动请求关闭"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
